package com.beforesunrise.project.server.bsservice.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.beforesunrise.project.server.bsservice.BsDataService;
import com.beforesunrise.project.server.bsservice.vo.BsSnsItem;
import com.beforesunrise.project.server.bsservice.vo.BsWhat;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Transaction;

public class BsDataServiceImpl implements BsDataService {
	
	protected static final String TBS_SNS_ITEM = "BS_SNS_ITEM";
	protected static final String TBS_WHAT = "BS_WHAT";
	
	protected static final String TBS_SNS_ITEM_COL1 = "UID";
	protected static final String TBS_SNS_ITEM_COL2 = "USER_ID";
	protected static final String TBS_SNS_ITEM_COL3 = "DATE";
	protected static final String TBS_SNS_ITEM_COL4 = "WHERE";
	protected static final String TBS_SNS_ITEM_COL5 = "COMMENT";
	
	protected static final String TBS_WHAT_COL1 = "UID";
	protected static final String TBS_WHAT_COL2 = "USER_ID";
	protected static final String TBS_WHAT_COL3 = "SNS_ITEM_ID";
	protected static final String TBS_WHAT_COL4 = "WHAT";


	@Override
	public Object insertSnsItem(BsSnsItem snsItem) throws Exception {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Transaction txn = datastore.beginTransaction();
		
		try {
			String snsItemId = UUID.randomUUID().toString();
			snsItem.setUid(snsItemId);
		    Entity snsItemEntity = new Entity(TBS_SNS_ITEM, snsItemId);
		    snsItemEntity.setProperty(TBS_SNS_ITEM_COL2, snsItem.getUserId());
		    snsItemEntity.setProperty(TBS_SNS_ITEM_COL3, snsItem.getDate());
		    snsItemEntity.setProperty(TBS_SNS_ITEM_COL4, snsItem.getWhere());
		    snsItemEntity.setProperty(TBS_SNS_ITEM_COL5, snsItem.getComment());

		    datastore.put(snsItemEntity);
		    
		    List<BsWhat> whatList = snsItem.getWhatList();
		    if(whatList != null && whatList.size() > 0)
		    {
		    	for(BsWhat whatItem : whatList)
		    	{
		    		String whatItemId = UUID.randomUUID().toString();
		    		Key key = KeyFactory.createKey(snsItemEntity.getKey(), TBS_WHAT, whatItemId);
		    		//BsWhat oldWhatItem = selectWhatItemByItemNUserNWhat(datastore, snsItem.getUserId(), whatItem.getWhat());
		    		
		    		//if(oldWhatItem == null)
		    		{
		    			whatItem.setUid(whatItemId);
		    			whatItem.setSnsItemId(snsItemId);
		    			whatItem.setUserId(snsItem.getUserId());
		    			
					    Entity whatEntity = new Entity(TBS_WHAT, key);
					    whatEntity.setProperty(TBS_WHAT_COL2, snsItem.getUserId());
					    whatEntity.setProperty(TBS_WHAT_COL3, snsItemId);
					    whatEntity.setProperty(TBS_WHAT_COL4, whatItem.getWhat());
					    
					    datastore.put(whatEntity);
		    		}
		    	}
		    }
		    
		    txn.commit();
		    return snsItem;
		}
		catch(Exception ex)
		{
			throw ex;
		}
		finally {
		    if (txn.isActive()) {
		        txn.rollback();
		    }
		}
	}

	@Override
	public Object updateSnsItem(BsSnsItem snsItem) throws Exception {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Transaction txn = datastore.beginTransaction();
		
		try {
		    
		    
		    txn.commit();
		    return null;
		}
		catch(Exception ex)
		{
			throw ex;
		}
		finally {
		    if (txn.isActive()) {
		        txn.rollback();
		    }
		}
	}

	@Override
	public void deleteSnsItem(String uid) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

	}

	@Override
	public BsSnsItem selectSnsItem(String uid) throws Exception {
		BsSnsItem snsItem = null;
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		
		Key key = KeyFactory.createKey(TBS_SNS_ITEM, uid);
		Entity snsItemEntity = datastore.get(key);

		if(snsItemEntity != null)
		{
			snsItem = new BsSnsItem();
			FillSnsItemFromEntity(snsItem, snsItemEntity);
			snsItem.setWhatList(selectWhatItemsBySnsItem(datastore, uid));
		}
	    
		return snsItem;
	}

	@Override
	public List<BsSnsItem> selectSnsItemsByUser(String userId) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		
		ArrayList<BsSnsItem> snsItemList = new ArrayList<BsSnsItem>();
		Query query = new Query(TBS_SNS_ITEM);
		query.addFilter(TBS_SNS_ITEM_COL2, Query.FilterOperator.EQUAL, userId);
		query.addSort(TBS_SNS_ITEM_COL3, Query.SortDirection.DESCENDING);
		PreparedQuery pq = datastore.prepare(query);

	    for (Entity result : pq.asIterable()) {
	    	BsSnsItem snsItem = new BsSnsItem();
	    	FillSnsItemFromEntity(snsItem, result);
			snsItemList.add(snsItem);
	    }
	    
		return snsItemList;
	}
	
	protected BsWhat selectWhatItemByUserNWhat(DatastoreService datastore, String userId, String what)
	{
		BsWhat whatItem = null;
		Query query = new Query(TBS_WHAT);
		query.addFilter(TBS_WHAT_COL2, Query.FilterOperator.EQUAL, userId);
		query.addFilter(TBS_WHAT_COL4, Query.FilterOperator.EQUAL, what);
		PreparedQuery pq = datastore.prepare(query);

	    for (Entity result : pq.asIterable()) {
	    	whatItem = new BsWhat();
	    	FillWhatItemFromEntity(whatItem, result);
	    	break;
	    }
	    
	    return whatItem;
	}

	protected List<BsWhat> selectWhatItemsBySnsItem(DatastoreService datastore, String snsItemId)
	{
		ArrayList<BsWhat> whatItemList = new ArrayList<BsWhat>();
		Query query = new Query(TBS_WHAT);
		query.addFilter(TBS_WHAT_COL3, Query.FilterOperator.EQUAL, snsItemId);
		PreparedQuery pq = datastore.prepare(query);

	    for (Entity result : pq.asIterable()) {
	    	BsWhat whatItem = new BsWhat();
	    	FillWhatItemFromEntity(whatItem, result);
	    	whatItemList.add(whatItem);
	    }
	    
	    return whatItemList;
	}
	
	protected void FillSnsItemFromEntity(BsSnsItem snsItem, Entity entity)
	{
		snsItem.setUid(entity.getKey().getName());
		snsItem.setUserId((String)entity.getProperty(TBS_SNS_ITEM_COL2));
		snsItem.setDate((Date)entity.getProperty(TBS_SNS_ITEM_COL3));
		snsItem.setWhere((String)entity.getProperty(TBS_SNS_ITEM_COL4));
		snsItem.setComment((String)entity.getProperty(TBS_SNS_ITEM_COL5));
	}
	
	protected void FillWhatItemFromEntity(BsWhat whatItem, Entity entity)
	{
		whatItem.setUid(entity.getParent().getName());
    	whatItem.setUserId((String) entity.getProperty(TBS_WHAT_COL2));
    	whatItem.setSnsItemId((String) entity.getProperty(TBS_WHAT_COL3));
    	whatItem.setWhat((String) entity.getProperty(TBS_WHAT_COL4));
	}
}
